package com.xyp.iodemo.nettyrpcserver.netty;

import com.xyp.iodemo.nettyrpcserver.utils.StaticData;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.net.InetSocketAddress;
import java.util.logging.Logger;

/**
 * @author xuyuanpeng
 * @version 1.0
 * @date 2019-03-06 14:47
 */
public class EchoServerImpl implements IEchoServer{
    private final Integer port;
    private static Boolean isRunning = false;
    private static Logger logger = Logger.getLogger("EchoServerImpl");

    public EchoServerImpl(int port){
        this.port=port;
    }

    @Override
    public void stop() {
        isRunning=false;
    }

    @Override
    public void start() throws Exception {
        logger.info("start");
        NioEventLoopGroup group=new NioEventLoopGroup();
        try {
            ServerBootstrap bootstrap=new ServerBootstrap();
            bootstrap.group(group)
                    //指定使用 NIO 的传输 Channel
                    .channel(NioServerSocketChannel.class)
                    //.设置 socket 地址使用所选的端口
                    .localAddress(new InetSocketAddress(port))
                    //添加 EchoServerHandler 到 Channel 的 ChannelPipeline
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            socketChannel.pipeline().addLast(new EchoServerHandler());
                        }
                    });
            //绑定的服务器;sync 等待服务器关闭
            ChannelFuture future=bootstrap.bind().sync();
            //关闭 channel 和 块，直到它被关闭
            future.channel().closeFuture().sync();
        }finally {
            //关机的 EventLoopGroup，释放所有资源。
            group.shutdownGracefully().sync();
        }
    }

    @Override
    public void register(Class serviceInterface, Class impl) {
        StaticData.serviceRegistry.put(serviceInterface.getName(), impl);
    }

    @Override
    public boolean isRunning() {
        return isRunning;
    }

    @Override
    public int getPort() {
        return this.port;
    }
}
